'''
Created on May 28, 2011

'''
from time import time
from game_agent import *
from loa_game import BLACK, WHITE
from utilities.frame_penalty import FramePenaltyUtil
from utilities.quads import Quads
from utilities.centerOfMass import CenterOfMass
from experimentClass.timeTestalpha_beta import TestTimeAalphaBeta
TIME = 0

class TestTimeBond(GameAgent):
    '''
    our agent
    '''
    DEBUG = False

    def __init__(self):
        '''
        Constructor
        '''
        self.setupTime = 0
        
    def move(self, game_state):
        '''
        This is the method called by the runner of this agent.
        It includes the code that decides the next move.
        
        @param game_state: The current game state.
        @return: The GameAction that the agent will execute in its next move.
        '''
        if self.DEBUG:
            print "********Bond State********"
            print game_state
            print "Player: ", game_state.getCurrentPlayer()
            print "**************************"
        value, action, reason = self.alphaBeta.search_anytime(game_state, True)
        init_depth = self.alphaBeta.max_depth
        depth = init_depth
        while reason != TIME:
            if self.DEBUG:
                print "*****CHANGING MAX DEPTH TO", self.alphaBeta.max_depth + 1
            self.alphaBeta.max_depth = self.alphaBeta.max_depth + 1
            temp_value, temp_action, reason = self.alphaBeta.search_anytime(game_state, False)
            temp_depth = self.alphaBeta.max_depth
            if (temp_value/temp_depth > value/depth):
                action = temp_action
                depth = temp_depth
        self.alphaBeta.max_depth = init_depth
        return action
    
    def setup(self, player, game_state, turn_time_limit = NO_LIMIT, setup_time_limit = NO_LIMIT):
        '''
        This is method is called once at the beginning of the game, 
        and enables the agent to prepare for things to come.
        
        @param player: Your player.
        @param game_state: The initial game state.
        @param turn_time_limit: The time that will be allocated for each turn.
        @param setup_time_limit: The time limit for setting up this agent.
        '''
        self.player     = player
        u               = lambda state, ancestor: FramePenaltyUtil(player).utility(state, ancestor)
        whiteQuads      = Quads(game_state.size, game_state.board, WHITE)
        blackQuads      = Quads(game_state.size, game_state.board, BLACK)
        whiteCom        = CenterOfMass(WHITE, game_state.size, game_state.board, True)
        blackCom        = CenterOfMass(BLACK, game_state.size, game_state.board, True)
        max_depth       = self.calc_max_depth(turn_time_limit)
        self.alphaBeta  = TestTimeAalphaBeta(self.player, max_depth, turn_time_limit, whiteCom, blackCom, whiteQuads, blackQuads)
        
    def calc_max_depth(self, turn_time_limit):
        '''
        Calculate the maximum calculation depth that can be done in the given time limit
        @param turn_time_limit: the time limit
        '''
        return 2

                    